use serde::Deserialize;
use serde_json::{json, Result, Value};

pub fn json_demo() {
  test_from_string();
  test_get();
  test_schema();
}

fn test_from_string() {
  fn untyped_example() -> Result<()> {
    // Some JSON input data as a &str. Maybe this comes from the user.
    let data = r#"
        {
            "name": "John Doe",
            "age": 43,
            "phones": [
                "+44 1234567",
                "+44 2345678"
            ]
        }"#;

    // Parse the string of data into serde_json::Value.
    let v = serde_json::from_str::<Value>(data)?;

    // Access parts of the data by indexing with square brackets.
    println!("Please call {} at the number {}", v["name"], v["phones"][0]);
    println!("Please call {} ", &v["age"]);

    let r1 = v["age"].as_i64().expect("msg");
    println!("{}", r1);
    Ok(())
  }
  untyped_example().expect("msg");
}

fn test_get() {
  let object = json!({ "A": 65, "B": 66, "C": 67 });
  assert_eq!(*object.get("A").unwrap(), json!(65));
  println!("Please call {}", object.get("A").unwrap());

  let array = json!(["A", "B", "C"]);
  assert_eq!(*array.get(2).unwrap(), json!("C"));
  println!("Please call {}", array.get(2).unwrap());

  assert_eq!(array.get("A"), None);
}

#[derive(Deserialize, Debug)]
struct User {
  fingerprint: String,
  location: String,
}

fn test_schema() {
  // The type of `j` is `serde_json::Value`
  let j = json!({
      "fingerprint": "0xF9BA143B95FF6D82",
      "location": "Menlo Park, CA"
  });

  let u: User = serde_json::from_value(j).unwrap();
  println!("{:#?}", u);
}
